﻿using SQLitePCL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UWP.Douban.Repositories
{
    public abstract class Repository
    {
        private string DbName = "Config.db";
        private readonly SQLiteConnection _connection;

        protected Repository()
        {
            _connection = new SQLiteConnection(DbName);
        }

        protected T Query<T>(string sql, Func<ISQLiteStatement, T> executor = null, params object[] bindValues)
        {
            using (var statement = _connection.Prepare(sql))
            {
                BindValues(bindValues, statement);

                var result = statement.Step();
                if (result == SQLiteResult.ROW)
                {
                    if (statement.ColumnCount > 0)
                    {
                        //有多个列。
                        if (statement.ColumnCount == 1)
                        {
                            return (T)statement[0];
                        }
                        if (executor != null)
                        {
                            return executor(statement);
                        }
                    }
                }
                return default(T);
            }
        }

        protected IEnumerable<T> QueryMore<T>(string sql, Func<ISQLiteStatement, T> executor = null,
            params object[] bindValues)
        {
            using (var statement = _connection.Prepare(sql))
            {
                BindValues(bindValues, statement);

                while (statement.Step() == SQLiteResult.ROW)
                {
                    if (statement.ColumnCount > 0)
                    {
                        //有多个列。
                        if (statement.ColumnCount == 1)
                        {
                            yield return (T)statement[0];
                        }
                        if (executor != null)
                        {
                            yield return executor(statement);
                        }
                    }
                }
                yield return default(T);
            }
        }




        protected SQLiteResult Execute(string sql, params object[] bindValues)
        {
            using (var statement = _connection.Prepare(sql))
            {
                BindValues(bindValues, statement);

                return statement.Step();
            }
        }



        private static void BindValues(object[] bindValues, ISQLiteStatement statement)
        {
            for (int i = 1; i <= bindValues.Count(); i++)
            {
                statement.Bind(i, bindValues[i - 1]);
            }
        }
    }
}
